<?php

namespace app\common\service;

use app\common\service\Recycle as RecycleService;
use think\facade\Db;

class Logic
{

    public function SubTable($data, $Model, $id, $InfoMode = [])
    {
        $sub = !empty($data['sub']) ? $data['sub'] : [];
        foreach ($sub as $k => $v) {
            $UpData[$v['sub_id']] = $id;
            $value = !empty($v['value']) ? $v['value'] : '';
            if ($value) {
                $where = "" . $v['sub_id'] . "='" . $value . "'";
                Db::name($v['database'])->where($where)->update($UpData);
            }
        }
        $keyFind = $Model->where("id='" . $id . "'")->find();
        $sub_database = $InfoMode['sub_database'];
        foreach ($sub_database as $k => $v) {
            if (empty($data[$v['alias']])) {
                return [];
            }
            if ($v['type'] == 1) {
                $where = $v['sub_field'] . "='" . $keyFind[$v['key_field']] . "'";
            } else {
                $where = $v['key_field'] . "='" . $keyFind[$v['sub_field']] . "'";
            }
            $find = Db::name($v['database'])->where($where)->count();
            $data[$v['alias']]['update_id'] = $data['a']['update_id'];
            $data[$v['alias']]['update_time'] = $data['a']['update_time'];
            if ($find == 0) {
                if ($v['type'] == 1) {
                    $data[$v['alias']][$v['sub_field']] = $id;
                    $data[$v['alias']]['create_id'] = $data['a']['update_id'];
                    $data[$v['alias']]['create_time'] = $data['a']['update_time'];
                    Db::name($v['database'])->insert($data[$v['alias']]);
                }
            } else {
                Db::name($v['database'])->where($where)->update($data[$v['alias']]);
            }
        }
        /*json子表一对多数据更新*/
        $json_sub = !empty($data['json_sub']) ? $data['json_sub'] : [];
        foreach ($json_sub as $k => $v) {
            $datas = !empty($v['value']) ? json_decode($v['value'], true) : [];
            $Db = Db::name($k);
            $ids = "0,";
            foreach ($datas as $k2 => $v2) {
                $v2[$v['sub_id']] = $id;
                $v2['update_id'] = $data['a']['update_id'];
                $v2['update_time'] = $data['a']['update_time'];
                $count = 0;
                if (!empty($v2['id'])) {
                    $count = $Db->where("id='" . $v2['id'] . "'")->count();
                }
                if (empty($count)) {
                    $v2['create_id'] = $data['a']['update_id'];
                    $v2['create_time'] = $data['a']['update_time'];
                    $ids .= $Db->insertGetId($v2) . ',';
                } else {
                    $ids .= $v2['id'] . ',';
                    $Db->where("id='" . $v2['id'] . "'")->update($v2);
                }
            }
            $Db->where("" . $v['sub_id'] . "='" . $id . "' and id NOT IN(" . rtrim($ids, ",") . ")")->delete();
        }
    }

    public function Detail($find = [], $params = [], $InfoForm = [], $InfoMode = [])
    {
        $sub_database = $InfoMode['sub_database'];
        $fields = $this->AllField($InfoForm);
        $detail['a'] = $find;
        foreach ($sub_database as $k => $v) {
            $detail[$v['alias']] = [];
            if ($find) {
                if ($v['type'] == 1) {
                    $where = $v['sub_field'] . "='" . $find[$v['key_field']] . "'";
                } else {
                    $where = $v['key_field'] . "='" . $find[$v['sub_field']] . "'";
                }
                $field = $this->FiledStr($fields, 'detail', $v['alias']);
                if ($field) {
                    $detail[$v['alias']] = Db::name($v['database'])->where($where)->field($field)->find();
                }
            }
        }
        $AllData = $this->GetData('detail', $detail, $params, $fields);
        $data = [];
        foreach ($AllData as $k => $v) {
            $table = $k;
            if (isset($fields[$table])) {
                foreach ($v as $k2 => $v2) {
                    $data[$table . '__' . $k2] = $v2;
                }
            } else {
                $data[$k] = $v;
            }
        }
        return $data;
    }

    public function AllField($data = [])
    {
        $layout = $data['layout'];
        $field = [];
        foreach ($layout as $k => $v) {
            $c = explode('__', $v['field']);
            $table = 'a';
            if (count($c) == 2) {
                $table = $c[0];
                $v['field'] = $c[1];
            }
            $field[$table][] = $v;
        }
        return $field;
    }

    public function FiledStr($fields = [], $type = 'add', $table = 'a')
    {
        $arr = !empty($fields[$table]) ? $fields[$table] : [];
        $str = '';
        foreach ($arr as $k => $v) {
            switch ($type) {
                case "add":
                    $str .= $v['field'] . ',';
                    break;
                case "edit":
                    $is_edit = !empty($v['is_edit']) ? $v['is_edit'] : 2;
                    if ($is_edit == 2) {
                        $str .= $v['field'] . ',';
                    }
                    break;
                case "detail":
                    $str .= $v['field'] . ',';
                    break;
            }
        }
        return rtrim($str, ",");
    }

    public function GetSource($InfoForm)
    {
        $layout = $InfoForm['layout'];
        $data = [];
        foreach ($layout as $k => $v) {
            if (!empty($v['options_num'])) {
                $options_num = explode('|', $v['options_num']);
                $data[$options_num[0]] = GetOptions($v['options_num']);
            }
            if (!empty($v['cols'])) {
                foreach ($v['cols'] as $k2 => $v2) {
                    if (!empty($v2['options'])) {
                        $options_num = explode('|', $v2['options']);
                        $data[$options_num[0]] = GetOptions($v2['options']);
                    }
                }
            }
        }
        return $data;
    }

    public function GetData($type, $find = [], $params = [], $fields = [], $Model = '')
    {
        $detail = [];
        if ($type != "detail") {
            $newFind = [];
            foreach ($params as $k => $v) {
                $c = explode('__', $k);
                $table = 'a';
                if (count($c) == 2) {
                    $table = $c[0];
                    $k = $c[1];
                }
                $newFind[$table][$k] = $v;
            }
            $find = $newFind;
            $params = $newFind;
        }

        foreach ($fields as $k => $v) {
            foreach ($v as $k2 => $v2) {
                $field = $v2['field'];
                $data = !empty($find[$k]) ? $find[$k] : [];
                $value = $this->GetValue($type, $data, $v2, $Model);
                if ($v2['tag'] == 'jsontable' && !empty($v2['database']) && !empty($v2['database_field'])) {
                    if ($type != 'detail') {
                        $detail['json_sub'][$v2['database']] = [
                            'sub_id' => $v2['database_field'],
                            'value' => $value,
                            'database' => $v2['database'],
                            'field' => $field,
                            'table' => $k
                        ];
                    }
                    if ($type == 'detail') {
                        if (!empty($params['id'])) {
                            $dbField = 'id';
                            foreach ($v2['cols'] as $k3 => $v3) {
                                $dbField .= "," . $v3['field'];
                            }
                            $t = Db::name($v2['database'])->where("" . $v2['database_field'] . "='" . $params['id'] . "'")->field($dbField)->orderRaw("id asc")->select()->toArray();
                            $value = !empty($t) ? json_encode($t, JSON_UNESCAPED_UNICODE) : '';
                        }
                    }

                }
                switch ($type) {
                    case "detail":
                        if ($k == "a") {
                            $detail[$field] = $value;
                        } else {
                            $detail[$k][$field] = $value;
                        }
                        break;
                    case "add":
                    case "edit":
                        $is_edit = !empty($v2['is_edit']) ? $v2['is_edit'] : 1;
                        if ($v2['tag'] == 'password' && $value) {
                            $value = md5($value);
                        }
                        if ($is_edit == 1) {
                            $detail[$k][$field] = $value;
                            if ($v2['tag'] == 'password' && empty($value) && $type == 'edit') {
                                unset($detail[$k][$field]);
                            }
                        }
                        break;
                }

                if ($k == 'sub' && $type != "detail") {
                    $detail[$k][$field] = [
                        'value' => $value,
                        'database' => $v2['database'],
                        'sub_id' => $v2['mode_sub_id'],
                    ];
                }


            }


        }
        if ($type == "detail") {
            $detail['id'] = !empty($find['a']['id']) ? $find['a']['id'] : '';
        }
        return $detail;
    }

    public function Validate($data)
    {
        $layout = $data['layout'];
        $arr = [];
        foreach ($layout as $k => $v) {
            $table = "a";
            $field = $v['field'];
            $c = explode('__', $v['field']);
            if (count($c) == 2) {
                $table = $c[0];
                $field = $c[1];
            }
            $required = !empty($v['required']) ? $v['required'] : 2;
            if ($required == 1) {
                $arr[] = ['tag' => $v['tag'], 'field' => $field, 'msg' => $v['title'] . '必填', 'rule' => 'required', 'table' => $table];
            }
            $only = !empty($v['only']) ? $v['only'] : 2;
            if ($only == 1) {
                $arr[] = ['tag' => $v['tag'], 'field' => $field, 'msg' => $v['title'] . '不可重复', 'rule' => 'only', 'table' => $table];
            }
            if (!empty($v['verify'])) {
                $arr[] = ['tag' => $v['tag'], 'field' => $field, 'msg' => $v['title'] . '值填写错误', 'rule' => $v['verify'], 'table' => $table];
            }
            if (!empty($v['cols']) && $v['tag'] == "jsontable") {
                $arr[] = ['tag' => 'cols', 'cols' => $v['cols'], 'field' => $field, 'msg' => $v['title'] . '必填', 'rule' => 'cols', 'table' => $table];
            }
        }
        return $arr;
    }


    public function GetValue($type, $data, $item, $Model)
    {
        $field = $item['field'];
        $value = isset($data[$field]) ? $data[$field] : '';
        if ($value == '') {
            $value = $item['value'];
            $t = explode("{", $value);
            if (count($t) == 2) {
                $f = str_replace("}", '', $t[1]);
                $value = input($f);
            } else {
                $value = input($field);
            }
        }
        if ($type == 'add' && !empty($item['num_rule'])) {
            $str = '';
            foreach ($item['num_rule'] as $kk => $vv) {
                $rule_val = $vv['rule_val'];
                switch ($vv['rule_type']) {
                    case 2:
                        $rule_val = str_replace("YYYY", date('Y'), $rule_val);
                        $rule_val = str_replace("MM", date('m'), $rule_val);
                        $rule_val = str_replace("DD", date('d'), $rule_val);
                        $rule_val = str_replace("HH", date('H'), $rule_val);
                        $rule_val = str_replace("II", date('i'), $rule_val);
                        $str .= str_replace("SS", date('s'), $rule_val);
                        break;
                    case 3:
                        $str .= $rule_val;
                        break;
                    case 4:
                        if ($Model) {
                            $val = '10000000000';
                            $max = substr($val, 0, $rule_val+1);
                            $num = $Model->count() + 1;
                            if ($num < $max) {
                                $num = str_pad($num, $rule_val, "0", STR_PAD_LEFT);
                            }
                            $str .= $num;
                        }
                        break;
                    default:
                        $val = '9999999999';
                        $max = substr($val, 0, $rule_val);
                        $min = substr($max + 1, 0, $rule_val);
                        $str .= rand($min, $max);
                }
            }
            $value = $str;
        }
        if (($type == "add" || $type == "edit") && $item['tag'] == "jsontable") {
            $vals = !empty($data[$field]) ? json_decode($data[$field], true) : [];
            $cols = $item['cols'];
            $newVal = [];
            foreach ($vals as $k2 => $v2) {
                $val = [];
                foreach ($cols as $k3 => $v3) {
                    $val[$v3['field']] = isset($v2[$v3['field']]) ? $v2[$v3['field']] : '';
                }
                $newVal[] = $val;
            }
            $value = json_encode($newVal, JSON_UNESCAPED_UNICODE);
        }
        if ($item['tag'] == "password" && $type == "detail") {
            $value = '';
        }


        return $value;
    }

    public function GetSubTable($InfoMode, $alias)
    {
        $data = [];
        $sub_database = $InfoMode['sub_database'];
        foreach ($sub_database as $k => $v) {
            if ($alias == $v['alias']) {
                $data = $v;
            }
        }
        return $data;
    }

    public function UpdateField($Model, $params, $InfoLists, $InfoMode)
    {
        $field = $params['field'];
        $is_edit = 2;
        foreach ($InfoLists as $k => $v) {
            $cols = $v['table_cols'];
            foreach ($cols as $k2 => $v2) {
                if ($field == $v2['field'] && $v2['update']) {
                    $is_edit = 1;
                }
            }
        }
        if ($is_edit == 2) {
            return ['code' => 203, 'msg' => '此字段不允许修改', 'data' => []];
        }
        $Db = $Model;
        $c = explode('__', $field);
        $upField = $params['field'];
        $where = "`id`='" . $params['id'] . "'";
        if (count($c) == 2) {
            $base = $this->GetSubTable($InfoMode);
            $Db = Db::name($base['database']);
            $keyFind = $Model->where("`id`='" . $params['id'] . "'")->find();
            if ($base['type'] == 1) {
                $where = $base['sub_field'] . "='" . $keyFind[$base['key_field']] . "'";
            } else {
                $where = $base['key_field'] . "='" . $keyFind[$base['sub_field']] . "'";
            }
            $upField = $c[1];
        }
        $Db->where($where)->Update([$upField => $params['value']]);
        return ['code' => 200, 'msg' => '修改成功', 'data' => []];
    }

    /*请注意：只有正向关联的数据才可关联删除*/
    public function Delete($Model, $params, $InfoMode)
    {
        $RecycleService = new RecycleService();
        $id = "";
        if (!empty($params['id'])) {
            $id = $params['id'];
        }
        if (!empty($params['ids'])) {
            $id = $params['ids'];
        }
        $RecycleService->DelAdd($Model, $id);//放入回收站
        $Model->where("`id` in(" . $id . ")")->delete();
        $sub_database = $InfoMode['sub_database'];
        foreach ($sub_database as $k => $v) {
            if ($v['type'] == 1) {
                $base = $v;
                Db::name($base['database'])->where("`" . $base['sub_field'] . "` in(" . $id . ")")->delete();
            }
        }
        return ['code' => 200, 'msg' => '删除成功', 'data' => []];
    }
}